// createShare 结果被各个组件引用的话，相当于只支持单例。
// 如果不同子树希望有各自的 share 互相独立互补干扰的话，则在 context 创建和传递 share
// 只需要一个 context 增加一个层级，就可以同时支持任意多个 share 在 context 内部使用

import React, { useCallback, useState, useContext } from 'react';
import { createShare } from '@/hooks/cross';
import * as theme from './theme';
import styles from './ContextShare.less';

// 默认的 share context，主要为了提供 TS 类型推断
const templateContext = {
  themeShare: createShare(theme.defaultTheme),
  share2: createShare(2),
  share3: createShare(3),
};
// context 限定多个共享空间，组件树的各个分支都可以有自己的一套 share 互补干扰
const ShareContext = React.createContext(templateContext);

function Provider() {
  const [state, setState] = useState(theme.defaultTheme);
  const { themeShare } = useContext(ShareContext);
  themeShare.useProvide(state);
  const onSwitch = useCallback(() => {
    setState((c) => (c === theme.defaultTheme) ? theme.theme2 : theme.defaultTheme)
  }, []);
  return (
    <div onClick={onSwitch}>change (provider)</div>
  )
}

function Injecter() {
  const { themeShare } = useContext(ShareContext);
  const [theme1] = themeShare.useInject();
  return (
    <div>
      <h5>Injecter</h5>
      <pre>{JSON.stringify(theme1, null, 2)}</pre>
    </div>

  )
}

function SubTree() {
  // 直接用一个 context 供应多套 share 空间，永远不变，稳定，不引发重渲染
  // 所有的 createShare 在特定的 context 创建时才制造出来
  const [shareMap] = useState(() => ({
    themeShare: createShare(theme.defaultTheme),
    share2: createShare(2),
    share3: createShare(3),
  }));


  console.log('render useShareType');
  return (
    <div>
      <ShareContext.Provider value={shareMap}>
        <Provider />
        <hr />
        <Injecter />
      </ShareContext.Provider>
    </div>
  );

}

export default function MultiContext() {
  return (
    <div className={styles.grid}>
      <SubTree />
      <SubTree />
      <SubTree />
    </div>
  )
}
